package com.example.workrecord.util;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.HttpMethod;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @ClassName: AliYunOssUtil
 * @Description: 阿里云公共OSS工具类
 * @Author: Wei
 * @Date: 2018/8/13 18:43
 * @Version: 1.0
 */
public class AliYunOssUtil {

    private AliYunOssUtil() {
        throw new IllegalStateException("Utility class");
    }

    private static final Logger logger=Logger.getLogger(AliYunOssUtil.class);

    private static String endpoint="http://oss-cn-shanghai.aliyuncs.com";
    private static String accessKeyId="LTAIFzFWVnZuPxVA";//
    //LTAIAlBhoYPlGAYG
    private static String accessKeySecret="CkA2OKNcK1v6Smd3UE3fMFIizoBqbN";
    //a9pxfWyb6bD7wFVgnjPRSGkXWBIt9I
    private static String bucketName="saic-public-2";//saic-public


    /**
     * 创建存储空间
     *
     * @param bucketName
     * @return
     */
    public static String createBucket(String bucketName) {
        String newName="";
        // 创建OSSClient实例。
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
            }
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return newName;
    }

    /**
     * 以文件流方式上传
     *
     * @param multipartFile
     * @return
     */
    public static String fileUpload(MultipartFile multipartFile, String bucketName) {
        String fileurl="";
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest=new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            ListBucketsRequest listBucketsRequest=new ListBucketsRequest();
            listBucketsRequest.setMaxKeys(500);
            System.out.println(multipartFile.getOriginalFilename());
            String ext=multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf('.'));
           String newName=System.currentTimeMillis() + Tools.getRandomNum3() + ext;

            // 上传文件流
            ossClient.putObject(bucketName, newName, multipartFile.getInputStream());
            fileurl=newName;
//// 创建请求。
//            GeneratePresignedUrlRequest generatePresignedUrlRequest=new GeneratePresignedUrlRequest(bucketName, newName);
//// HttpMethod为PUT。
//            generatePresignedUrlRequest.setMethod(HttpMethod.PUT);
//// 添加用户自定义元信息。
//            generatePresignedUrlRequest.addUserMetadata("author", "hzhw");
//// 添加Content-Type。
//            generatePresignedUrlRequest.setContentType("application/octet-stream");
//// 设置URL过期时间为1小时。
//            Calendar nowTime = Calendar.getInstance();
//            nowTime.add(Calendar.MINUTE, 5);
//            Date expiration = nowTime.getTime();
//            generatePresignedUrlRequest.setExpiration(expiration);
//// 生成签名URL。
//            URL url=ossClient.generatePresignedUrl(generatePresignedUrlRequest);
//            fileurl=url.toString();
//            System.out.println(url);
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return fileurl;
    }

    /**
     * 以Byte数组方式上传
     *
     * @param fileName  文件名称
     * @param img64Byte base64位字符串
     * @return
     */
    public static String byteUpload(String fileName, String img64Byte, String bucketName) {
        BASE64Decoder decoder=new BASE64Decoder();
        String newName="";
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            byte[] content=decoder.decodeBuffer(img64Byte);
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest=new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            ListBucketsRequest listBucketsRequest=new ListBucketsRequest();
            listBucketsRequest.setMaxKeys(500);
            String ext=fileName.substring(fileName.lastIndexOf('.'));
            newName=System.currentTimeMillis() + Tools.getRandomNum3() + ext;
            // 上传文件流
            ossClient.putObject(bucketName, newName, new ByteArrayInputStream(content));
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
        return newName;
    }

    /**
     * @param fileName
     * @param fileType
     * @return
     * @throws IOException
     */
    public JSONObject fileDowload(String fileName, String fileType) throws Exception {
        // 创建OSSClient实例。
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        String objectName=fileName + System.currentTimeMillis() + "." + fileType;
        // 生成签名URL。
        Calendar nowTime=Calendar.getInstance();
        nowTime.add(Calendar.MINUTE, 5);
        Date expiration=nowTime.getTime();
        GeneratePresignedUrlRequest request=new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.PUT);
        // 设置过期时间。
        request.setExpiration(expiration);
        // 设置Content-Type。
        request.setContentType("application/octet-stream");
        // 添加用户自定义元信息。
        request.addUserMetadata("author", "alievent");
        // 生成签名URL（HTTP PUT请求）。
        URL signedUrl=ossClient.generatePresignedUrl(request);
        System.out.println("signed url for putObject: " + signedUrl);

        JSONObject object=new JSONObject();
        object.put("objectName", objectName);
        object.put("signedUrl", signedUrl.toString());
        return object;
    }

    /**
     * 删除单个文件
     *
     * @param key
     */
    public static void deleteObject(String key, String bucketName) {
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 删除Object
            ossClient.deleteObject(bucketName, key);
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }

    }

    /**
     * 删除多个文件
     *
     * @param keys
     */
    public static void deleteObjects(List<String> keys, String bucketName) {
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 删除Objects
            ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(keys));
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
    }


    public static void uploadFileStream(InputStream inputStream, String fileName) {
        OSSClient ossClient=new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            ossClient.doesBucketExist(bucketName);
            ossClient.putObject(bucketName, fileName, inputStream);
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (Exception e) {
            logger.error(e.getMessage());
        } finally {
            ossClient.shutdown();
        }
    }


}
